/**
 * Copyright (C) BFH www.bfh.ch 2011
 * Code written by: Patrick Dobler, Marc Folly
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package ch.bfh.ti.kybernetik.gui.swing;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import net.miginfocom.swing.MigLayout;
import ch.bfh.ti.kybernetik.engine.model.LightSensor;
import ch.bfh.ti.kybernetik.engine.model.Motor;
import ch.bfh.ti.kybernetik.engine.model.Roboter;
import ch.bfh.ti.kybernetik.gui.slick.components.RoboterComponent;

/**
 * A {@link JFrame} which renders a input mask to edit a selected
 * {@link Roboter}
 * 
 */
class EditRoboterFrame extends JFrame {

	private static final long serialVersionUID = 1L;

	private final RoboterComponent roboterComponent;

	private JTextField roboterMaxLightSensor;

	private JSlider roboterLightSensorAngles;

	private JSlider roboterLightSensorDistance;

	private JSlider roboterMotorDistance;

	private JSlider roboterLightSensorViewField;

	EditRoboterFrame(RoboterComponent roboterComponent) {
		super();
		setTitle("Edit Roboter");
		setSize(350, 400);
		setLocationRelativeTo(null);
		setDefaultCloseOperation(DISPOSE_ON_CLOSE);
		this.roboterComponent = roboterComponent;
		this.init();
	}

	private void init() {
		JPanel panel = new JPanel(new MigLayout());
		getContentPane().add(panel);

		panel.add(new JLabel("Roboter ID:"));
		panel.add(new JLabel("" + roboterComponent.hashCode()), "wrap");

		panel.add(new JLabel("Max Light Sensor Value"));
		panel.add(getRoboterMaxLightSensorInputField(), "wrap");

		panel.add(new JLabel("Light Sensor Angle"));
		panel.add(getRoboterLightSensorAngles(), "wrap");

		panel.add(new JLabel("Light Sensor View Field"));
		panel.add(getRoboterLightSensorViewField(), "wrap");

		panel.add(new JLabel("Light Sensor Distance"));
		panel.add(getRoboterLightSensorDistance(), "wrap");

		panel.add(new JLabel("Motor Distance"));
		panel.add(getRoboterMotorDistance(), "wrap");
	}

	private JSlider getRoboterMotorDistance() {
		if (roboterMotorDistance == null) {
			final Motor leftMotor = roboterComponent.getModelObject().getLeftMotor();
			final Motor rightMotor = roboterComponent.getModelObject().getRightMotor();
			roboterMotorDistance = new JSlider(JSlider.HORIZONTAL, 1, 180, (int) rightMotor.getDistanceX());
			initJSlider(roboterMotorDistance);
			roboterMotorDistance.addChangeListener(new ChangeListener() {
				@Override
				public void stateChanged(ChangeEvent e) {
					JSlider source = (JSlider) e.getSource();
					int value = source.getValue();
					leftMotor.setDistanceX(-value);
					rightMotor.setDistanceX(value);
				}
			});
		}
		return roboterMotorDistance;
	}

	private JSlider getRoboterLightSensorAngles() {
		if (roboterLightSensorAngles == null) {
			final LightSensor leftLightSensor = roboterComponent.getModelObject().getLeftLightSensor();
			final LightSensor rightLightSensor = roboterComponent.getModelObject().getRightLightSensor();
			roboterLightSensorAngles = new JSlider(JSlider.HORIZONTAL, 0, 180, (int) rightLightSensor.getElementAngle());
			initJSlider(roboterLightSensorAngles);
			roboterLightSensorAngles.addChangeListener(new ChangeListener() {
				@Override
				public void stateChanged(ChangeEvent e) {
					JSlider source = (JSlider) e.getSource();
					int value = source.getValue();
					leftLightSensor.setElementAngle(-value);
					rightLightSensor.setElementAngle(value);
				}
			});
		}
		return roboterLightSensorAngles;
	}

	private JSlider getRoboterLightSensorViewField() {
		if (roboterLightSensorViewField == null) {
			final LightSensor leftLightSensor = roboterComponent.getModelObject().getLeftLightSensor();
			final LightSensor rightLightSensor = roboterComponent.getModelObject().getRightLightSensor();
			roboterLightSensorViewField = new JSlider(JSlider.HORIZONTAL, 1, 180, (int) rightLightSensor.getViewFieldSize());
			initJSlider(roboterLightSensorViewField);
			roboterLightSensorViewField.addChangeListener(new ChangeListener() {
				@Override
				public void stateChanged(ChangeEvent e) {
					JSlider source = (JSlider) e.getSource();
					int value = source.getValue();
					leftLightSensor.setViewFieldSize(value);
					rightLightSensor.setViewFieldSize(value);
				}
			});
		}
		return roboterLightSensorViewField;
	}

	private JSlider getRoboterLightSensorDistance() {
		if (roboterLightSensorDistance == null) {
			final LightSensor leftLightSensor = roboterComponent.getModelObject().getLeftLightSensor();
			final LightSensor rightLightSensor = roboterComponent.getModelObject().getRightLightSensor();
			roboterLightSensorDistance = new JSlider(JSlider.HORIZONTAL, 1, 180, (int) rightLightSensor.getDistanceX());
			initJSlider(roboterLightSensorDistance);
			roboterLightSensorDistance.addChangeListener(new ChangeListener() {
				@Override
				public void stateChanged(ChangeEvent e) {
					JSlider source = (JSlider) e.getSource();
					int value = source.getValue();
					leftLightSensor.setDistanceX(-value);
					rightLightSensor.setDistanceX(value);
				}
			});
		}
		return roboterLightSensorDistance;
	}

	private JTextField getRoboterMaxLightSensorInputField() {
		if (roboterMaxLightSensor == null) {
			roboterMaxLightSensor = new JTextField(100);
			final LightSensor leftLightSensor = roboterComponent.getModelObject().getLeftLightSensor();
			final LightSensor rightLightSensor = roboterComponent.getModelObject().getRightLightSensor();
			roboterMaxLightSensor.setText(String.valueOf(leftLightSensor.getMaxLightIntensity()));
			roboterMaxLightSensor.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					int value = Integer.valueOf(roboterMaxLightSensor.getText());
					leftLightSensor.setMaxLightIntensity(value);
					rightLightSensor.setMaxLightIntensity(value);

				}
			});
		}
		return roboterMaxLightSensor;
	}

	private void initJSlider(JSlider jslider) {
		// jslider.setPaintLabels(true);
		jslider.setMajorTickSpacing(10);
		jslider.setPaintTicks(true);
	}

	// private void linkJTextFieldWithValue(final JTextField jTextField, final
	// Object bean, final String property,
	// final ActionPerformedHook hook) throws IllegalAccessException,
	// InvocationTargetException, NoSuchMethodException {
	// initJTextFieldWithDefaultValue(jTextField, bean, property);
	// addJTextFieldActionListener(jTextField, bean, property, hook);
	// }
	//
	// private void initJTextFieldWithDefaultValue(final JTextField jTextField,
	// final Object bean, final String property)
	// throws IllegalAccessException, InvocationTargetException,
	// NoSuchMethodException {
	// String beanValue = BeanUtils.getSimpleProperty(bean, property);
	// jTextField.setText(beanValue);
	// }
	//
	// private void addJTextFieldActionListener(final JTextField jTextField,
	// final Object bean, final String property,
	// final ActionPerformedHook hook) {
	// jTextField.addActionListener(new ActionListener() {
	// @Override
	// public void actionPerformed(ActionEvent actionEvent) {
	// try {
	// BeanUtils.setProperty(bean, property, jTextField.getText());
	// if (hook != null) {
	// hook.actionPerformed(jTextField.getText());
	// }
	// } catch (Exception e) {
	// e.printStackTrace();
	// }
	//
	// }
	// });
	// }

	// public interface ActionPerformedHook {
	//
	// void actionPerformed(String text);
	//
	// }
}
